<template>
  <view class="snake-game-container">
    <!-- 头部信息 -->
    <view class="game-header">
      <view class="header-title">贪吃蛇</view>
      <view class="user-info">{{ userName }}</view>
      <view class="score-info">分数: {{ gameState.scores[userId] || 0 }}</view>
      <view class="game-tip">{{ gameTip }}</view>
    </view>

    <!-- 游戏区域 -->
    <view class="game-area">
      <h2 class="game-title"><i class="fa fa-apple"></i> 贪吃蛇对战</h2>

      <!-- 玩家列表 -->
      <view class="player-list">
        <view class="player-card" :class="{ 'ready': players[0]?.ready }">{{ players[0]?.user_name || '等待加入...' }}
          <view class="status">{{ players[0]?.ready ? '已准备' : '未准备' }}</view>
        </view>
        <view class="player-card" :class="{ 'ready': players[1]?.ready }">{{ players[1]?.user_name || '等待加入...' }}
          <view class="status">{{ players[1]?.ready ? '已准备' : '未准备' }}</view>
        </view>
      </view>

      <!-- 游戏画布 -->
      <canvas canvas-id="snakeCanvas" class="game-canvas" @touchstart="handleTouchStart" @touchmove="handleTouchMove"></canvas>

      <!-- 控制按钮 -->
      <view class="control-buttons">
        <button @tap="startGame" v-if="!isGameStarted" class="start-btn">开始游戏</button>
        <button @tap="restartGame" v-if="isGameOver" class="restart-btn">重新开始</button>
        <button @tap="toggleReadyStatus" class="ready-btn">{{ isReady ? '取消准备' : '准备' }}</button>
        <button @tap="backToLobby" class="back-btn">返回大厅</button>
      </view>

      <!-- 操纵杆 -->
      <view class="joystick" v-if="isMobile">
        <view class="joystick-row">
          <button @tap="changeDirection('UP')" class="dir-btn">↑</button>
        </view>
        <view class="joystick-row">
          <button @tap="changeDirection('LEFT')" class="dir-btn">←</button>
          <button @tap="changeDirection('RIGHT')" class="dir-btn">→</button>
        </view>
        <view class="joystick-row">
          <button @tap="changeDirection('DOWN')" class="dir-btn">↓</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted, reactive, computed } from 'vue';
import { useRouter } from 'vue-router';

// 路由实例
const router = useRouter();

// 游戏状态
const gameState = reactive({
  status: 'waiting', // waiting, playing, gameover
  snakes: {},
  foods: [],
  scores: {},
  gridSize: 16,
  cellSize: 20
});

// 响应式变量
const userId = ref('');
const userName = ref('');
const roomId = ref('');
const players = ref([]);
const isReady = ref(false);
const isGameStarted = ref(false);
const isGameOver = ref(false);
const gameTip = ref('等待玩家加入...');
const isMobile = ref(false);
const touchStart = ref({ x: 0, y: 0 });
let gameInterval = null;
let ws = null;

/**
 * 初始化游戏
 */
function initGame() {
  // 重置游戏状态
  gameState.status = 'waiting';
  gameState.snakes = {};
  gameState.foods = [];
  gameState.scores = {};

  // 添加当前玩家的蛇
  gameState.snakes[userId.value] = {
    segments: [
      { x: 8, y: 8 },
      { x: 7, y: 8 },
      { x: 6, y: 8 }
    ],
    direction: 'RIGHT',
    alive: true
  };

  // 初始化分数
  gameState.scores[userId.value] = 0;

  // 生成食物
  gameState.foods = [generateFood(), generateFood()];

  // 渲染游戏
  renderGame();
}

/**
 * 生成食物
 */
function generateFood() {
  // 随机生成食物位置
  const x = Math.floor(Math.random() * gameState.gridSize);
  const y = Math.floor(Math.random() * gameState.gridSize);

  // 检查是否与蛇重叠
  for (const uid in gameState.snakes) {
    const snake = gameState.snakes[uid];
    for (const segment of snake.segments) {
      if (segment.x === x && segment.y === y) {
        // 如果重叠，重新生成
        return generateFood();
      }
    }
  }

  return { x, y };
}

/**
 * 渲染游戏
 */
function renderGame() {
  const ctx = uni.createCanvasContext('snakeCanvas');
  const canvasWidth = gameState.gridSize * gameState.cellSize;
  const canvasHeight = gameState.gridSize * gameState.cellSize;

  // 清除画布
  ctx.clearRect(0, 0, canvasWidth, canvasHeight);

  // 绘制网格背景
  ctx.setFillStyle('#f1f5f9');
  ctx.fillRect(0, 0, canvasWidth, canvasHeight);

  ctx.setStrokeStyle('#e2e8f0');
  for (let i = 0; i <= gameState.gridSize; i++) {
    // 垂直线
    ctx.beginPath();
    ctx.moveTo(i * gameState.cellSize, 0);
    ctx.lineTo(i * gameState.cellSize, canvasHeight);
    ctx.stroke();

    // 水平线
    ctx.beginPath();
    ctx.moveTo(0, i * gameState.cellSize);
    ctx.lineTo(canvasWidth, i * gameState.cellSize);
    ctx.stroke();
  }

  // 渲染食物
  gameState.foods.forEach(food => {
    ctx.setFillStyle('#f59e42');
    ctx.beginPath();
    ctx.arc(
      food.x * gameState.cellSize + gameState.cellSize / 2,
      food.y * gameState.cellSize + gameState.cellSize / 2,
      gameState.cellSize / 2 - 2,
      0, 2 * Math.PI
    );
    ctx.fill();
  });

  // 渲染所有蛇
  Object.entries(gameState.snakes).forEach(([uid, snake]) => {
    const isCurrentPlayer = uid === userId.value;
    const headColor = isCurrentPlayer ? '#6366f1' : '#22c55e';
    const bodyColor = isCurrentPlayer ? '#a5b4fc' : '#bbf7d0';

    for (let j = 0; j < snake.segments.length; j++) {
      const segment = snake.segments[j];
      const isHead = j === 0;

      ctx.setFillStyle(isHead ? headColor : bodyColor);
      ctx.fillRect(
        segment.x * gameState.cellSize + 1,
        segment.y * gameState.cellSize + 1,
        gameState.cellSize - 2,
        gameState.cellSize - 2
      );

      // 为蛇头添加眼睛
      if (isHead) {
        ctx.setFillStyle('#ffffff');

        // 根据方向绘制眼睛
        const eyeSize = gameState.cellSize / 5;
        const eyeOffset = gameState.cellSize / 4;

        let leftEyeX, leftEyeY, rightEyeX, rightEyeY;

        switch (snake.direction) {
          case 'RIGHT':
            leftEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset * 2;
            leftEyeY = segment.y * gameState.cellSize + eyeOffset;
            rightEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset * 2;
            rightEyeY = segment.y * gameState.cellSize + gameState.cellSize - eyeOffset;
            break;
          case 'LEFT':
            leftEyeX = segment.x * gameState.cellSize + eyeOffset * 2;
            leftEyeY = segment.y * gameState.cellSize + eyeOffset;
            rightEyeX = segment.x * gameState.cellSize + eyeOffset * 2;
            rightEyeY = segment.y * gameState.cellSize + gameState.cellSize - eyeOffset;
            break;
          case 'UP':
            leftEyeX = segment.x * gameState.cellSize + eyeOffset;
            leftEyeY = segment.y * gameState.cellSize + eyeOffset * 2;
            rightEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset;
            rightEyeY = segment.y * gameState.cellSize + eyeOffset * 2;
            break;
          case 'DOWN':
            leftEyeX = segment.x * gameState.cellSize + eyeOffset;
            leftEyeY = segment.y * gameState.cellSize + gameState.cellSize - eyeOffset * 2;
            rightEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset;
            rightEyeY = segment.y * gameState.cellSize + gameState.cellSize - eyeOffset * 2;
            break;
          default:
            leftEyeX = segment.x * gameState.cellSize + eyeOffset;
            leftEyeY = segment.y * gameState.cellSize + eyeOffset;
            rightEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset;
            rightEyeY = segment.y * gameState.cellSize + eyeOffset;
        }

        // 绘制左眼
        ctx.beginPath();
        ctx.arc(leftEyeX, leftEyeY, eyeSize, 0, 2 * Math.PI);
        ctx.fill();

        // 绘制右眼
        ctx.beginPath();
        ctx.arc(rightEyeX, rightEyeY, eyeSize, 0, 2 * Math.PI);
        ctx.fill();
      }
    }
  });

  ctx.draw();
}

/**
 * 开始游戏
 */
function startGame() {
  if (gameState.status === 'playing') return;

  gameState.status = 'playing';
  isGameStarted.value = true;
  isGameOver.value = false;
  gameTip.value = '游戏开始！';

  // 启动游戏循环
  if (gameInterval) clearInterval(gameInterval);
  gameInterval = setInterval(updateGame, 200);
}

/**
 * 更新游戏状态
 */
function updateGame() {
  // 移动所有蛇
  Object.entries(gameState.snakes).forEach(([uid, snake]) => {
    if (!snake.alive) return;

    const head = { ...snake.segments[0] };

    // 根据方向移动头部
    switch (snake.direction) {
      case 'UP':
        head.y--;
        break;
      case 'DOWN':
        head.y++;
        break;
      case 'LEFT':
        head.x--;
        break;
      case 'RIGHT':
        head.x++;
        break;
    }

    // 检查是否撞墙
    if (head.x < 0 || head.x >= gameState.gridSize || head.y < 0 || head.y >= gameState.gridSize) {
      snake.alive = false;
      return;
    }

    // 检查是否撞到自己或其他蛇
    let collision = false;
    Object.values(gameState.snakes).forEach(otherSnake => {
      for (let i = 0; i < otherSnake.segments.length; i++) {
        // 允许头部接触自己的尾部
        if (otherSnake === snake && i === otherSnake.segments.length - 1) continue;

        if (otherSnake.segments[i].x === head.x && otherSnake.segments[i].y === head.y) {
          collision = true;
          break;
        }
      }
    });

    if (collision) {
      snake.alive = false;
      return;
    }

    // 检查是否吃到食物
    let ate = false;
    for (let i = 0; i < gameState.foods.length; i++) {
      const food = gameState.foods[i];
      if (food.x === head.x && food.y === head.y) {
        // 吃到食物，增加分数
        gameState.scores[uid] = (gameState.scores[uid] || 0) + 1;
        // 生成新食物
        gameState.foods[i] = generateFood();
        // 蛇身增长
        snake.segments.unshift(head);
        ate = true;
        break;
      }
    }

    if (!ate) {
      // 没吃到食物，移动蛇
      snake.segments.unshift(head);
      snake.segments.pop();
    }
  });

  // 检查游戏是否结束
  let aliveCount = 0;
  for (const uid in gameState.snakes) {
    if (gameState.snakes[uid].alive) aliveCount++;
  }

  if (aliveCount <= 0 || (Object.keys(gameState.snakes).length > 1 && aliveCount <= 1)) {
    gameState.status = 'gameover';
    gameTip.value = '游戏结束！';
    clearInterval(gameInterval);
    gameInterval = null;
    isGameOver.value = true;
    isGameStarted.value = false;
  }

  // 更新UI
  renderGame();
}

/**
 * 重新开始游戏
 */
function restartGame() {
  initGame();
  startGame();
}

/**
 * 切换准备状态
 */
function toggleReadyStatus() {
  isReady.value = !isReady.value;
  gameTip.value = isReady.value ? '已准备' : '未准备';
  // 这里应该发送WebSocket消息通知其他玩家
}

/**
 * 改变蛇的方向
 */
function changeDirection(dir) {
  const snake = gameState.snakes[userId.value];
  if (!snake || !snake.alive) return;

  // 防止180度转向
  if (
    (dir === 'UP' && snake.direction === 'DOWN') ||
    (dir === 'DOWN' && snake.direction === 'UP') ||
    (dir === 'LEFT' && snake.direction === 'RIGHT') ||
    (dir === 'RIGHT' && snake.direction === 'LEFT')
  ) {
    return;
  }

  snake.direction = dir;
}

/**
 * 处理触摸开始事件
 */
function handleTouchStart(e) {
  touchStart.value = {
    x: e.touches[0].clientX,
    y: e.touches[0].clientY
  };
}

/**
 * 处理触摸移动事件
 */
function handleTouchMove(e) {
  e.preventDefault();
  if (!touchStart.value.x || !touchStart.value.y) return;

  const touchEnd = {
    x: e.touches[0].clientX,
    y: e.touches[0].clientY
  };

  const dx = touchEnd.x - touchStart.value.x;
  const dy = touchEnd.y - touchStart.value.y;

  // 确定滑动方向
  if (Math.abs(dx) > Math.abs(dy)) {
    // 水平滑动
    changeDirection(dx > 0 ? 'RIGHT' : 'LEFT');
  } else {
    // 垂直滑动
    changeDirection(dy > 0 ? 'DOWN' : 'UP');
  }

  // 重置触摸起点
  touchStart.value = touchEnd;
}

/**
 * 返回游戏大厅
 */
function backToLobby() {
  // 清理游戏资源
  if (gameInterval) {
    clearInterval(gameInterval);
    gameInterval = null;
  }
  if (ws) {
    try {
      ws.close();
    } catch (e) {}
    ws = null;
  }

  // 导航回游戏空间
  router.push('/pages/games/index');
}

/**
 * 检测设备类型
 */
function checkDeviceType() {
  const res = uni.getSystemInfoSync();
  isMobile.value = res.platform === 'android' || res.platform === 'ios';
}

// 生命周期钩子
onMounted(() => {
  // 检查设备类型
  checkDeviceType();

  // 获取用户信息和房间ID (实际应用中应该从登录状态或URL参数获取)
  // 这里只是示例，实际项目中需要替换为真实的获取方式
  userId.value = 'user123';
  userName.value = '玩家1';
  roomId.value = 'room456';

  // 初始化游戏
  initGame();

  // 初始化玩家列表
  players.value = [
    { user_id: userId.value, user_name: userName.value, ready: false },
    { user_id: 'user789', user_name: '等待加入...', ready: false }
  ];

  // 监听键盘事件 (仅在非移动设备上)
  if (!isMobile.value) {
    uni.onKeyDown(e => {
      switch (e.keyCode) {
        case 38: // 上
          changeDirection('UP');
          break;
        case 40: // 下
          changeDirection('DOWN');
          break;
        case 37: // 左
          changeDirection('LEFT');
          break;
        case 39: // 右
          changeDirection('RIGHT');
          break;
        case 13: // 回车
          if (!isGameStarted.value) startGame();
          else if (isGameOver.value) restartGame();
          break;
      }
    });
  }
});

onUnmounted(() => {
  // 清理游戏资源
  if (gameInterval) {
    clearInterval(gameInterval);
    gameInterval = null;
  }
  if (ws) {
    try {
      ws.close();
    } catch (e) {}
    ws = null;
  }

  // 移除键盘事件监听
  if (!isMobile.value) {
    uni.offKeyDown();
  }
});
</script>

<style scoped>
.snake-game-container {
  padding: 16px;
  min-height: 100vh;
  background: linear-gradient(135deg, #e0e7ff 0%, #f8fafc 100%);
}

.game-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 10px;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.header-title {
  font-size: 18px;
  font-weight: bold;
  color: #6366f1;
}

.user-info {
  font-size: 14px;
  color: #1f2937;
}

.score-info {
  font-size: 14px;
  color: #1f2937;
}

.game-tip {
  font-size: 14px;
  color: #6b7280;
}

.game-area {
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 4px 32px rgba(99, 102, 241, 0.2);
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.game-title {
  font-size: 18px;
  font-weight: bold;
  color: #4f46e5;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
}

.game-title i {
  margin-right: 8px;
}

.player-list {
  display: flex;
  justify-content: space-between;
  width: 100%;
  max-width: 320px;
  margin-bottom: 16px;
  gap: 10px;
}

.player-card {
  flex: 1;
  background: #f3f4f6;
  border-radius: 10px;
  padding: 10px;
  text-align: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.player-card.ready {
  border: 2px solid #4ade80;
}

.status {
  font-size: 12px;
  color: #6b7280;
  margin-top: 4px;
}

.player-card.ready .status {
  color: #4ade80;
}

.game-canvas {
  width: 320px;
  height: 320px;
  background: #f1f5f9;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(99, 102, 241, 0.1);
  margin-bottom: 20px;
}

.control-buttons {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  flex-wrap: wrap;
  justify-content: center;
}

.start-btn, .restart-btn, .ready-btn, .back-btn {
  padding: 8px 16px;
  border-radius: 50px;
  font-weight: bold;
  border: none;
  cursor: pointer;
  transition: all 0.2s;
}

.start-btn, .restart-btn {
  background: linear-gradient(90deg, #6366f1 0%, #818cf8 100%);
  color: white;
}

.ready-btn {
  background: #f3f4f6;
  color: #1f2937;
}

.back-btn {
  background: #fee2e2;
  color: #dc2626;
}

.start-btn:hover, .restart-btn:hover {
  opacity: 0.9;
  transform: scale(1.05);
}

.joystick {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.joystick-row {
  display: flex;
  justify-content: center;
}

.dir-btn {
  width: 40px;
  height: 40px;
  margin: 5px;
  border-radius: 50%;
  background: linear-gradient(90deg, #6366f1 0%, #818cf8 100%);
  color: white;
  font-size: 18px;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
  transition: all 0.2s;
}

.dir-btn:hover {
  opacity: 0.9;
  transform: scale(1.05);
}
</style>